home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
chasm01.sha
/
grammar.y
< prev
next >
Wrap
Text File
|
1995-03-23
|
5KB
|
348 lines
/*
* grammar.y - yacc parser
*
* @(#)grammar.y 1.1 91/04/10
*
* Copyright (c) 1991 Steve Scherf
*
* Author: Steve Scherf
* Date: Wed Apr 10 22:53:11 PDT 1991
*
*/
%{
#include <stdio.h>
extern char *vartab[];
extern int bcnt;
extern int svin;
int lineno = 1;
int pars_err;
%}
/* input token definitions */
%token STRING
%token REG
%token VAR
%token CONST
%token LABEL
/* instruction token definitions */
%token ADD
%token AND
%token BCD
%token CLD
%token DATA
%token DEF
%token DMP
%token DSP
%token INK
%token JMP
%token JOF
%token JSR
%token MEM
%token MOV
%token OR
%token RES
%token RET
%token RND
%token SAR
%token SEQ
%token SHL
%token SHR
%token SIP
%token SNE
%token SNP
%token SSC
%token SUB
%token XOR
%% /* rules section */
line : /* empty */
| line inst '\n'
{
lineno++;
}
| line error '\n'
{
lineno++;
yyerrok;
}
;
inst : /* empty */
| ADD const ',' REG
{
add_inst(lineno, 0x7, $4, 1, 0x0, 0, $2, 2);
}
| ADD REG ',' REG
{
add_inst(lineno, 0x8, $4, 1, $2, 1, 0x4, 1);
}
| ADD REG ',' VAR
{
if($4 == 2)
add_inst(lineno, 0xF, $2, 1, 0x0, 0, 0x1E, 2);
else
yyerror("illegal variable usage");
}
| AND REG ',' REG
{
add_inst(lineno, 0xF, $2, 1, $4, 1, 0x2, 1);
}
| BCD REG
{
add_inst(lineno, 0xF, $2, 1, 0x0, 0, 0x33, 2);
}
| CLD
{
add_inst(lineno, 0x0, 0x0, 0, 0x0, 0, 0x0E0, 3);
}
| DATA dlist
{
add_str_list();
}
| DEF LABEL ',' const
{
register int i;
i = add_lab($2);
lineno++;
add_val(i, $4);
lineno--;
}
| DMP REG
{
add_inst(lineno, 0xF, $2, 1, 0x0, 0, 0x55, 2);
}
| DSP const ',' REG ',' REG
{
add_inst(lineno, 0xD, $4, 1, $6, 1, $2, 1);
}
| INK REG
{
add_inst(lineno, 0xF, $2, 1, 0x0, 0, 0x0A, 2);
}
| JMP const
{
add_inst(lineno, 0x1, 0x0, 0, 0x0, 0, $2, 3);
}
| JOF const
{
add_inst(lineno, 0xB, 0x0, 0, 0x0, 0, $2, 3);
}
| JSR const
{
add_inst(lineno, 0x2, 0x0, 0, 0x0, 0, $2, 3);
}
| MEM const
{
add_pad($2);
}
| MOV const ',' REG
{
add_inst(lineno, 0x6, $4, 1, 0x0, 0, $2, 2);
}
| MOV REG ',' REG
{
add_inst(lineno, 0x8, $4, 1, $2, 1, 0x0, 1);
}
| MOV const ',' VAR
{
if($4 == 2)
add_inst(lineno, 0xA, 0x0, 0, 0x0, 0, $2, 3);
else
yyerror("illegal variable usage");
}
| MOV REG ',' VAR
{
switch($4) {
case 0:
add_inst(lineno, 0xF, $2, 1, 0x0, 0, 0x15, 2);
break;
case 1:
add_inst(lineno, 0xF, $2, 1, 0x0, 0, 0x18, 2);
break;
case 2:
yyerror("illegal variable usage");
break;
}
}
| MOV VAR ',' REG
{
if($2 == 0)
add_inst(lineno, 0xF, $4, 1, 0x0, 0, 0x07, 2);
else
yyerror("illegal variable usage");
}
| OR REG ',' REG
{
add_inst(lineno, 0x8, $4, 1, $2, 1, 0x1, 1);
}
| RES REG
{
add_inst(lineno, 0xF, $2, 1, 0x0, 0, 0x65, 2);
}
| RET
{
add_inst(lineno, 0x0, 0x0, 0, 0x0, 0, 0x0EE, 3);
}
| RND const ',' REG
{
add_inst(lineno, 0xC, $4, 1, 0x0, 0, $2, 2);
}
| SAR REG ',' REG
{
add_inst(lineno, 0x8, $4, 1, $2, 1, 0x7, 1);
}
| SEQ REG ',' REG
{
add_inst(lineno, 0x5, $2, 1, $4, 1, 0x0, 1);
}
| SEQ const ',' REG
{
add_inst(lineno, 0x3, $4, 1, 0x0, 0, $2, 2);
}
| SHL REG
{
add_inst(lineno, 0x8, $2, 1, 0x0, 0, 0x0E, 2);
}
| SHR REG
{
add_inst(lineno, 0x8, $2, 1, 0x0, 0, 0x06, 2);
}
| SIP REG
{
add_inst(lineno, 0xE, $2, 1, 0x0, 0, 0x9E, 2);
}
| SNE const ',' REG
{
add_inst(lineno, 0x4, $4, 1, 0x0, 0, $2, 2);
}
| SNE REG ',' REG
{
add_inst(lineno, 0x9, $2, 1, $4, 1, 0x0, 1);
}
| SNP REG
{
add_inst(lineno, 0xE, $2, 1, 0x0, 0, 0xA1, 2);
}
| SSC REG
{
add_inst(lineno, 0xF, $2, 1, 0x0, 0, 0x29, 2);
}
| SUB REG ',' REG
{
add_inst(lineno, 0x8, $4, 1, $2, 1, 0x5, 1);
}
| XOR REG ',' REG
{
add_inst(lineno, 0x8, $4, 1, $2, 1, 0x3, 1);
}
| LABEL ':'
{
if(svin != -1) {
add_val(svin, 0);
yyerror("duplicate label");
}
svin = add_lab($1);
}
;
dlist : dlent
| dlist ',' dlent
| dlist ',' newln dlent
;
dlent : const
{
add_con(lineno, $1);
$$ = $1;
}
| STRING
{
add_str(lineno, (char *)$1);
$$ = $1;
}
;
const : CONST
{
if($1 > 0xFFF || $1 < 0) {
yyerror("constant out of range");
$$ = 0;
}
else
$$ = $1;
}
| LABEL
{
register int i;
i = add_lab($1);
$$ = ((i + 1) << 12) + 0xFFF;
}
newln : '\n'
{
lineno++;
}
| newln '\n'
{
lineno++;
}
;
%% /* C code */
yyerror(s)
char *s;
{
printf("line %d: %s\n", lineno, s);
pars_err = 1;
}